template<typename T, typename E>
class expected {
    private:
        union {
            T m_value;
            E m_error;
        };
        bool m_valid;
    public:
    T & get()   
    {
        if ( !m_valid)
        {
            throw std::logic_error("Missing a value");
        }
    }

    E & error()
    {
        if (m_value)
        {
            throw std::logic_error("There is no error");
        }
        return m_error;
    }

    template<typename... Args>
    static expected success(Args&&... params)
    {
        expected result;
        result.m_valid = true;
        new (&result.m_value)
            T(std::forward<Args>(params)...)
        return result;
    }

    template<typename... Args>
    static expected error(Args&&... params)
    {
        expected result;
        result.m_valid = false;
        new (&result.m_error) E(std::forward<Args>(params)...);
        return result;
    }

    ~expected()
    {
        if (m_valid)
        {
            m_value.~T();
        } else {
            m_error.~E();
        }
    }
    //复制
    expected(const expected& other): m_valid(other.m_valid)
    {
        if (m_valid) {
            new (&m_value)T(other.m_value);
        } else {
            new (&m_error)E(other.m_error);
        }
    }
    //移动
    expected(expected&& other):m_valid(other.m_valid)
    {
        if(m_valid) {
            new (&m_value)T(std::move(other.m_value));
        } else {
            new (&m_error)E(std::move(other.m_error));
        }
    }
    void swap(expected& other)
    {
        using std::swap;
        if(m_valid) {
            if(other.m_valid) {
                swap(m_value, other.m_value);
            } else {
                //如果other值有错误，先把other保存到临时对象中，再把值移到other中，然后就可以安全地把错误赋值给自己的对象了。
                auto temp = std::move(other.m_error);
                other.m_error.~E()
                new (&other.m_value)T(std::move(m_value));
                m_value.~T();
                new (&m_error)E(std::move(temp));
                std::swap(m_valid, other.m_valid);
            }
        } else {
            if (other.m_valid) {
                other.swap(*this);
            } else {
                swap(m_error, other.m_error);
            }
        }
    }
    expected& operator=(expected other)
    {
        swap(other);
        return *this;
    }

    operator bool() const
    {
        return m_valid();
    }

    operator std::optional<T>() const
    {
        if (m_valid)
        {
            return m_value;
        } else {
            return std::optional<T>();
        }
    }

    template <typename T, template Variant, template Expected = expected<T, std::string>>
    Expected get_if(const Variant& variant)
    {
        T* ptr = std::get_if<T>(variant);
        if (ptr)
        {
            return Expected::success(*ptr);
        } else {
            return Expected::error("Variant doesn't contain the desired type");
        }
    }
};